#ifndef PHP_TIDEWAYS_XHPROF_H
#define PHP_TIDEWAYS_XHPROF_H

extern zend_module_entry tideways_xhprof_module_entry;
#define phpext_tideways_xhprof_ptr &tideways_xhprof_module_entry

#define PHP_TIDEWAYS_XHPROF_VERSION "5.0.2"
#define TIDEWAYS_XHPROF_CALLGRAPH_COUNTER_SIZE 1024
#define TIDEWAYS_XHPROF_CALLGRAPH_SLOTS 8192
#define TIDEWAYS_XHPROF_CLOCK_CGT 0
#define TIDEWAYS_XHPROF_CLOCK_GTOD 1
#define TIDEWAYS_XHPROF_CLOCK_TSC 2
#define TIDEWAYS_XHPROF_CLOCK_MACH 3
#define TIDEWAYS_XHPROF_CLOCK_QPC 4
#define TIDEWAYS_XHPROF_CLOCK_NONE 255

#ifndef TSRMLS_CC
#define TSRMLS_FETCH()
#define TSRMLS_CC
#define TSRMLS_DC
#define TSRMLS_D
#define TSRMLS_C
#endif

#ifdef ZTS
#include "TSRM.h"
#endif

#if !defined(uint32)
typedef unsigned int uint32;
#endif

#if !defined(uint64)
typedef unsigned long long uint64;
#endif

typedef struct xhprof_frame_t xhprof_frame_t;

typedef struct xhprof_callgraph_bucket_t {
    zend_ulong key;
    zend_string *parent_class;
    zend_string *parent_function;
    int parent_recurse_level;
    zend_string *child_class;
    zend_string *child_function;
    int child_recurse_level;
    struct xhprof_callgraph_bucket_t *next;
    zend_long count;
    zend_long wall_time;
    zend_long cpu_time;
    zend_long memory;
    zend_long memory_peak;
    long int            num_alloc, num_free;
    long int            amount_alloc;
} xhprof_callgraph_bucket;

/* Tracer maintains a stack of entries being profiled.
 *
 * This structure is a convenient place to track start time of a particular
 * profile operation, recursion depth, and the name of the function being
 * profiled. */
struct xhprof_frame_t {
    struct xhprof_frame_t   *previous_frame;        /* ptr to prev entry being profiled */
    zend_string         *function_name;
    zend_string         *class_name;
    uint64              wt_start;           /* start value for wall clock timer */
    uint64              cpu_start;         /* start value for CPU clock timer */
    long int            mu_start;                    /* memory usage */
    long int            pmu_start;              /* peak memory usage */
    long int            num_alloc, num_free;
    long int            amount_alloc;
    int                 recurse_level;
    zend_ulong          hash_code;          /* hash_code for the function name  */
};

ZEND_BEGIN_MODULE_GLOBALS(tideways_xhprof)
    int enabled;
    uint64 start_timestamp;
    uint64 start_time;
    int clock_source;
    zend_bool clock_use_rdtsc;
    double timebase_factor;
    zend_string *root;
    xhprof_frame_t *callgraph_frames;
    xhprof_frame_t *frame_free_list;
    zend_ulong function_hash_counters[TIDEWAYS_XHPROF_CALLGRAPH_COUNTER_SIZE];
    xhprof_callgraph_bucket* callgraph_buckets[TIDEWAYS_XHPROF_CALLGRAPH_SLOTS];
    zend_long flags;
    long int num_alloc;
    long int num_free;
    long int amount_alloc;
ZEND_END_MODULE_GLOBALS(tideways_xhprof)

#if defined(__GNUC__) && __GNUC__ >= 4
#	define PHP_TIDEWAYS_XHPROF_API __attribute__ ((visibility("default")))
#else
#	define PHP_TIDEWAYS_XHPROF_API
#endif

#define TIDEWAYS_LOGO_DATA_URI ""

#if defined(ZTS) && defined(COMPILE_DL_TIDEWAYS_XHPROF)
ZEND_TSRMLS_CACHE_EXTERN()
#endif

#endif	/* PHP_TIDEWAYS_XHPROF_H */

